/* FeatureIDE - An IDE to support feature-oriented software development * Copyright (C) 2005-2009 FeatureIDE Team, University of Magdeburg * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * * See http://www.fosd.de/featureide/ for further information. */ package featureide.fm.ui.editors.featuremodel; import java.io.File; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.draw2d.Graphics; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.SWTGraphics; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.gef.GraphicalViewer; import org.eclipse.gef.LayerConstants; import org.eclipse.gef.editparts.LayerManager; import org.eclipse.gef.editparts.ScalableFreeformRootEditPart; import org.eclipse.gef.ui.parts.GraphicalViewerImpl; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.ImageLoader; import org.eclipse.ui.progress.UIJob; /** * Saves the figures of an GEF editor into a bitmap file. * * @author Thomas Thuem */ public class GEFImageWriter { public static void writeToFile(final GraphicalViewerImpl graphicalViewer, final File file) { UIJob job = new UIJob("Save image") { @Override public IStatus runInUIThread(IProgressMonitor monitor) { saveEditorContentsAsImage(graphicalViewer, file.toString()); return Status.OK_STATUS; } }; job.schedule(); } private static void saveEditorContentsAsImage(GraphicalViewer viewer, String saveFilePath) { Image image = drawFigureOnImage(viewer); Image croppedImage = cropImage(image); image.dispose(); saveImage(croppedImage, saveFilePath); croppedImage.dispose(); } private static Image drawFigureOnImage(GraphicalViewer viewer) { IFigure figure = getRootFigure(viewer); Rectangle bounds = figure.getBounds(); Image image = new Image(null, bounds.width, bounds.height); GC imageGC = new GC(image); Graphics imgGraphics = new SWTGraphics(imageGC); imgGraphics.translate(-bounds.x, -bounds.y); figure.paint(imgGraphics); imgGraphics.translate(bounds.x, bounds.y); imageGC.dispose(); return image; } private static Image cropImage(Image image) { int border = 5; Rectangle r = calculateUsedRectangle(image); Image img2 = new Image(null, r.width + 2 * border, r.height + 2 * border); GC imageGC2 = new GC(img2); Graphics imgGraphics2 = new SWTGraphics(imageGC2); imgGraphics2.drawImage(image, r, new Rectangle(border, border, r.width, r.height)); return img2; } private static void saveImage(Image image, String saveFilePath) { int format = readFormatFromFileName(saveFilePath); ImageData[] data = new ImageData[1]; data[0] = image.getImageData(); ImageLoader loader = new ImageLoader(); loader.data = data; loader.save(saveFilePath, format); } private static IFigure getRootFigure(GraphicalViewer viewer) { ScalableFreeformRootEditPart rootEditPart = (ScalableFreeformRootEditPart) viewer .getEditPartRegistry().get(LayerManager.ID); IFigure rootFigure = ((LayerManager) rootEditPart) .getLayer(LayerConstants.PRINTABLE_LAYERS); return rootFigure; } private static Rectangle calculateUsedRectangle(Image image) { ImageData data = image.getImageData(); Rectangle r = new Rectangle(); int bg = data.getPixel(0, 0); for (int x = 0; x < data.width; x++) for (int y = 0; y < data.height; y++) if (data.getPixel(x, y) != bg) { r.x = x; x = data.width; break; } for (int x = data.width - 1; x >= 0; x--) for (int y = 0; y < data.height; y++) if (data.getPixel(x, y) != bg) { r.width = x - r.x + 1; x = 0; break; } for (int y = 0; y < data.height; y++) for (int x = 0; x < data.width; x++) if (data.getPixel(x, y) != bg) { r.y = y; y = data.height; break; } for (int y = data.height - 1; y >= 0; y--) for (int x = 0; x < data.width; x++) if (data.getPixel(x, y) != bg) { r.height = y - r.y + 1; y = 0; break; } return r; } private static int readFormatFromFileName(String saveFilePath) { String file = saveFilePath.toLowerCase(); if (file.endsWith(".bmp")) return SWT.IMAGE_BMP; if (file.endsWith(".gif")) return SWT.IMAGE_GIF; if (file.endsWith(".ico")) return SWT.IMAGE_ICO; if (file.endsWith(".jpg")) return SWT.IMAGE_JPEG; if (file.endsWith(".jpeg")) return SWT.IMAGE_JPEG; if (file.endsWith(".png")) return SWT.IMAGE_PNG; if (file.endsWith(".tif")) return SWT.IMAGE_TIFF; throw new RuntimeException("Unknown image file format " + saveFilePath); } }